﻿function RoomTable(selector, floorsCount, firstFloor) {
    var me = this;
    var table = $(selector);
    if (table.length != 1 || table.is("table") == false) {
        throw new Error("选择对象有误");
    }
    floorsCount = parseInt(floorsCount);
    if (isNaN(floorsCount) || floorsCount < 1) {
        throw new Error("floorsCount参数必须大于1");
    }
    table.empty();
    var row1 = $("<tr><td>单元</td></tr>");
    var row2 = $("<tr><td>#</td></tr>");
    var tbody = $("<tbody />")
    table.append(tbody);
    tbody.append(row1);
    tbody.append(row2);
    if (!firstFloor) {
        firstFloor = 1;
    } else if (firstFloor < 0) {
        floorsCount++;
    }
    for (var i = floorsCount - 1; i >= 0; i--) {
        if (-firstFloor == i) {
            i--;
        }
        tbody.append("<tr><td>" + (i + firstFloor) + "</td></tr>");
    }
    var rows = tbody.find("tr:gt(1)");

    this.OnCellClick = function (e) {
        if (e.subRoomNumber != 0) {
            return (e.unitTitle + "|" + e.floorNumber + "层|第" + e.roomNumber + "户-" + e.subRoomNumber);
        }
        return (e.unitTitle + "|" + e.floorNumber + "层|第" + e.roomNumber + "户");
    };

    function BindData(unit, floor, room, subroom) {
        this.unitTitle = row1.find("[place=" + unit + "]").text();
        this.unitNumber = parseInt(unit);
        this.floorNumber = parseInt(floor);
        this.roomNumber = parseInt(room);
        this.subRoomNumber = parseInt(subroom) || 0;
        this.place = [unit, floor, room, this.subRoomNumber];
    };

    //编辑模式
    var editPattern = false;
    var bindclick = function (e) {
        var $this = $(e.currentTarget);
        e.stopPropagation();
        if (editPattern === true) {
            if ($this.is(".btn-primary")) {
                $this.removeClass("btn-primary");
                return;
            }
            $this.addClass("btn-primary");
            var tds = rows.find(".btn-primary");
            if (me.GetRelation(tds) == 0) {
                tds.not($this).removeClass("btn-primary");
                return;
            }
            return;
        }
        if (me.OnCellClick && me.OnCellClick.constructor === Function) {
            $("div[roomtopic]").remove();
            var colsCount = row2.find("td").length - 1;
            var bindinfo = $this.data("bindinfo");
            var txt = me.OnCellClick.apply(e.currentTarget, [bindinfo]);
            var topic = $("<div roomtopic style='position:absolute;border:solid 1px black;background:white;padding:5px;' />")
                .text(txt);

            var position = $this.position();
            var parent = $this.parents("table");
            $this.offsetParent().append(topic);

            var top = position.top;
            if (position.top > parent.height() / 2) {
                top = (position.top - topic.outerHeight() + $this.outerHeight());
            }

            var left = position.left + $this.outerWidth();
            if (position.left > parent.width() / 2) {
                left = position.left - topic.outerWidth();//- $this.outerWidth();
            }

            topic.css({
                top: top + "px",
                left: left + "px"
            });
        }
    }

    var unitNumber = 0;
    //绑定事件
    this.OnBinding = function (e) {
        if (e.subRoomNumber != 0) {
            return $(this).text(e.subRoomNumber);
        }
        return $(this).text([e.unitNumber, e.floorNumber, ("0" + e.roomNumber).slice(0, 2)].join(""));
    };

    //添加单元
    this.AddUnit = function (unitName, roomCount, types) {
        unitNumber++;
        row1.append($("<td />").text(unitName).prop("colspan", roomCount).attr("place", unitNumber));
        for (var i = 0; i < roomCount; i++) {
            row2.append($("<td />").text(types[i] || "选择户型"));
        }

        rows.each(function (i, ele) {
            var tr = $(ele);
            var floorNumber = tr.find("td:first").text();
            for (var j = 0; j < roomCount; j++) {
                var td = $("<td />");
                var bindinfo = new BindData(unitNumber, floorNumber, j + 1);
                td.attr("place", bindinfo.place.join(","));
                tr.append(td.data("bindinfo", bindinfo).click(bindclick));
                if (me.OnBinding && me.OnBinding.constructor === Function) {
                    me.OnBinding.apply(td, [bindinfo]);
                }
            }
        });

        //绑定移除提示框事件
        if (!$(window).data("bindevent_roomtopic")) {
            $(window).data("bindevent_roomtopic", true).click(function () {
                $("div[roomtopic]").remove();
            });
        }

    };

    //获取数据中数据的规则,0无规则 1相同 2相邻
    var arrayRule = function (array) {
        if (array.length < 1) {
            throw Error("数组必须大于1")
        }
        array = array.sort(function (a, b) { return a < b });
        var j = array[0] - array[1];
        if (j != 0 && j != 1) {
            return 0;
        }
        for (var i = 1; i < array.length - 1; i++) {
            if (array[i] - array[i + 1] != j) {
                return 0
            }
        }
        return j + 1;
    };

    //获取当前单元格所表示的房间的模式 0正常 1拆分 2横向合并 3纵向合并
    this.GetMode = function (room) {
        room = rows.find(room);
        if (room.length == 0) {
            throw Error("房间不存在");
        }
        var place = room.attr("place");
        if (!place) {
            throw Error("房间不存在");
        }
        if (/,0/.test(place) == false) {
            return 1;
        }
        var places = place.split("|");
        if (places.length == 1) {
            return 0;
        }
        var arr = [];
        $.each(places, function (i, n) {
            arr.push(n.split(","));
        });
        var a = arrayRule($.map(arr, function (d) { return parseInt(d[0]); }));
        var b = arrayRule($.map(arr, function (d) { return parseInt(d[1]); }));
        var c = arrayRule($.map(arr, function (d) { return parseInt(d[2]); }));
        var d = arrayRule($.map(arr, function (d) { return parseInt(d[3]); }));

        if (a != 1 || d != 1) {
            throw Error("房间数据有误");
        }
        if (b == 2 && c == 1) {
            return 3;
        }
        if (b == 1 && c == 2) {
            return 2;
        }
        throw Error("房间数据有误");
    };

    this.GetSelectorRoom = function () {
        return rows.find(".btn-primary");
    };

    //获取所有房间的关系,0 无关系 1横向相邻 2 纵向相邻
    this.GetRelation = function (tds) {
        tds = $(tds || me.GetSelectorRoom());
        if (tds.length < 2) {
            return 0;
        }
        var units = [];
        var floors = [];
        var rooms = [];

        for (var i = 0; i < tds.length; i++) {
            if (me.GetMode(tds[i]) != 0) {
                return 0;
            }
            var bindinfo = tds.eq(i).data("bindinfo");
            units.push(bindinfo.unitNumber);
            floors.push(bindinfo.floorNumber);
            rooms.push(bindinfo.roomNumber);
        }

        var a = arrayRule(units);
        var b = arrayRule(floors);
        var c = arrayRule(rooms);

        if (a != 1) {
            return 0;
        }
        if (b == 1 && c == 2) {
            return 1;
        }
        if (b == 2 && c == 1) {
            return 2;
        }
        return 0;
    };

    //横向合并
    this.RoomsMerge = function (unit, floor, rooms) {
        if (arrayRule(rooms) != 2) {
            throw Error("只能合并相邻的房间");
        }
        var tds = $(null);
        var place = [];
        for (var i = 0; i < rooms.length; i++) {
            var td = rows.find("td[place*='" + [unit, floor, rooms[i], 0].join(",") + "']");
            if (me.GetMode(td) != 0) {
                throw Error("部分房间不允许参与合并");
            }
            tds = tds.add(td);
            place.push([unit, floor, rooms[i], 0].join(","));
        }
        var td = $("<td />").prop("colspan", rooms.length);
        tds.eq(0).after(td);
        tds.remove();

        var bindinfo = new BindData(unit, floor, rooms[rooms.length - 1]);
        td.data("bindinfo", bindinfo).attr("place", place.join("|")).click(bindclick);
        if (me.OnBinding && me.OnBinding.constructor === Function) {
            me.OnBinding.apply(td, [bindinfo]);
        }
    };

    //纵向合并
    this.FloorsMerge = function (unit, floors, room) {
        if (arrayRule(floors) != 2) {
            throw Error("只能合并相邻的房间");
        }
        var tds = $(null);
        var place = [];
        for (var i = 0; i < floors.length; i++) {
            var td = rows.find("td[place*='" + [unit, floors[i], room, 0].join(",") + "']");
            if (me.GetMode(td) != 0) {
                throw Error("部分房间不允许参与合并");
            }
            tds = tds.add(td);
            place.push([unit, floors[i], room, 0].join(","));
        }
        var td = $("<td />").prop("rowspan", floors.length);
        tds.eq(0).after(td);
        tds.remove();

        var bindinfo = new BindData(unit, floors[floors.length - 1], room);
        td.data("bindinfo", bindinfo).attr("place", place.join("|")).click(bindclick);
        if (me.OnBinding && me.OnBinding.constructor === Function) {
            me.OnBinding.apply(td, [bindinfo]);
        }
    };

    //编辑模式下使用
    this.Merge = function () {
        if (editPattern !== true) {
            throw Error("请先调用BeginEdit()方法!");
        }
        var rooms = me.GetSelectorRoom();
        if (rooms.length < 2) {
            alert("房间少于2个无法合并");
            return;
        }
        var bindinfo = rooms.eq(0).data("bindinfo");
        switch (me.GetRelation(rooms)) {
            case 1:
                me.RoomsMerge(bindinfo.unitNumber, bindinfo.floorNumber, $.map(rooms, function (ele) {
                    return $(ele).data("bindinfo").roomNumber;
                }));
                return;
            case 2:
                me.FloorsMerge(bindinfo.unitNumber, $.map(rooms, function (ele) {
                    return $(ele).data("bindinfo").floorNumber;
                }), bindinfo.roomNumber);
                return;
            default:
                throw Error("system error!");
        }
    };

    //还原
    this.Undo = function () {
        if (editPattern !== true) {
            throw Error("请先调用BeginEdit()方法!");
        }
        var rooms = me.GetSelectorRoom();
        if (rooms.length != 1) {
            alert("无需还原操作");
            return;
        }
        var mode = me.GetMode(rooms[0]);
        if (mode == 0) {
            alert("无需还原操作");
            return;
        }
        var bindinfo = rooms.eq(0).data("bindinfo");
        if (mode == 1) {
            var $td = rooms.parent("td");
            $td.empty();
            bindinfo = new BindData(bindinfo.unitNumber, bindinfo.floorNumber, bindinfo.roomNumber);
            $td.attr("place", bindinfo.place.join(","));
            $td.append($td.data("bindinfo", bindinfo).click(bindclick));
            if (me.OnBinding && me.OnBinding.constructor === Function) {
                me.OnBinding.apply($td, [bindinfo]);
            }
            return;
        }
        var count = rooms.prop("colspan"); //横向合并
        if (count) {
            for (var i = 0; i < count; i++) {
                var $td = $("<td />");
                bindinfo = new BindData(bindinfo.unitNumber, bindinfo.floorNumber, bindinfo.roomNumber + i);
                $td.attr("place", bindinfo.place.join(","));
                $td.append($td.data("bindinfo", bindinfo).click(bindclick));
                if (me.OnBinding && me.OnBinding.constructor === Function) {
                    me.OnBinding.apply($td, [bindinfo]);
                }
                rooms.before($td);
            }
            rooms.remove();
            return;
        }

    };

    //拆分
    this.Split = function (unit, floor, room, count) {
        if (editPattern === true) {
            var rooms = me.GetSelectorRoom();
            if (rooms.length == 0) {
                alert("请选择要合并的房间");
                return;
            }
            if (rooms.length != 1) {
                alert("选择的房间太多");
                return;
            }
            count = prompt("请输入拆分房间个数!(只能是2,3,4)");
            if (count != 2 && count != 3 && count != 4) {
                alert("输入有误!只能是2,3,4");
                return;
            }
            var bindinfo = rooms.eq(0).data("bindinfo");
            unit = bindinfo.unitNumber;
            floor = bindinfo.floorNumber;
            room = bindinfo.roomNumber;
            rooms.removeClass("btn-primary");
        }
        var td = rows.find("td[place*='" + [unit, floor, room, 0].join(",") + "']");
        var mode = me.GetMode(td);
        if (mode != 0 && mode != 3) {
            throw Error("该房间不允许拆分");
        }
        var bindinfo = td.data("bindinfo");
        var place = td.attr("place");
        td.after((td = td.clone())).remove();
        td.removeData("bindinfo");
        td.removeAttr("place");
        td.empty();

        var div = "<div style='height:100%;border:solid 1px black;display:inline-block' />";
        for (var i = 0; i < count; i++) {
            var bindinfo = new BindData(bindinfo.unitNumber, bindinfo.floorNumber, bindinfo.roomNumber, i + 1);
            var $div = $(div).data("bindinfo", bindinfo).css("width", (100 / count) + "%");
            td.append($div.attr("place", bindinfo.place.join(",")).click(bindclick));
            if (me.OnBinding && me.OnBinding.constructor === Function) {
                me.OnBinding.apply($div[0], [bindinfo]);
            }
        }
    };

    this.BeginEdit = function () {
        table.css("border-color", "red");
        editPattern = true;
    };

    this.EndEdit = function () {
        editPattern = false;
        table.css("border-color", "");
        me.GetSelectorRoom().removeClass("btn-primary");
    }
}